package com.atmilan.quartz.service.impl;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.atmilan.quartz.constant.enums.ProductTypeEnum;
import com.atmilan.quartz.model.dto.crmeb.StoreProductCrmebRequest;
import com.atmilan.quartz.model.dto.jst.JstProductResDTO;
import com.atmilan.quartz.model.dto.jst.JstProductResDTO.DataResult;
import com.atmilan.quartz.model.dto.jst.JstProductResDTO.Sku;
import com.atmilan.quartz.model.dto.jst.JstProductStockResDTO;
import com.atmilan.quartz.model.dto.jst.JstProductStockResDTO.Inventory;
import com.atmilan.quartz.model.entity.buyer.StoreProductAttrValueDraft;
import com.atmilan.quartz.model.entity.buyer.StoreProductDraft;
import com.atmilan.quartz.model.entity.crmeb.StoreProduct;
import com.atmilan.quartz.model.entity.crmeb.StoreProductAttrValue;
import com.atmilan.quartz.model.entity.jst.JstProduct;
import com.atmilan.quartz.model.entity.jst.JstProductSku;
import com.atmilan.quartz.service.IJstProductService;
import com.atmilan.quartz.service.IJstProductSkuService;
import com.atmilan.quartz.service.IJstSyncService;
import com.atmilan.quartz.service.IStoreProductAttrService;
import com.atmilan.quartz.service.IStoreProductAttrValueDraftService;
import com.atmilan.quartz.service.IStoreProductAttrValueService;
import com.atmilan.quartz.service.IStoreProductDraftService;
import com.atmilan.quartz.service.IStoreProductService;
import com.atmilan.quartz.service.ISystemConfigService;
import com.atmilan.quartz.sync.push.crmeb.domain.StoreProductAttrValueRequest;
import com.atmilan.quartz.utils.RedisUtil;
import com.atmilan.quartz.utils.product.JstProductUtil;
import com.atmilan.quartz.utils.source.SourceJstProductUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * @author daigb
 * @date:  2021-12-29 15:02
 */
@Slf4j
@Service
public class JstSyncServiceImpl implements IJstSyncService {
    @Autowired
    SourceJstProductUtil sourceJstProductUtil;
    @Autowired
    RedisUtil redisUtil;
    @Autowired
    ISystemConfigService systemConfigService;
    @Autowired
    IJstProductService jstProductService;
    @Autowired
    IJstProductSkuService jstProductSkuService;
    @Autowired
    IStoreProductService storeProductService;
    @Autowired
    IStoreProductAttrService storeProductAttrService;
    @Autowired
    IStoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    JstProductUtil jstProductUtil;
    @Autowired
    IStoreProductDraftService storeProductDraftService;
    @Autowired
    IStoreProductAttrValueDraftService storeProductAttrValueDraftService;
    
    /**
     * 获取远程数据并保存到数据源
     */
    @Override
    public Boolean syncProduct() {
        // 数据清空
        jstProductService.deleteAll();
        jstProductSkuService.deleteAll();

        long millis = System.currentTimeMillis();
        LocalDate startTime = LocalDate.parse("2018-09-28");
        LocalDate endTime = startTime.plusDays(1);
		while (LocalDate.now().plusDays(2).isAfter(endTime)) {
            int pageNo = 1;
			int pageCount = 1;
			while (pageNo <= pageCount) {
				try {
					JstProductResDTO jstProductResDTO = jstProductUtil.productPage(pageNo, startTime + " 00:00:00", endTime + " 00:00:00");
                    if (null != jstProductResDTO && CollectionUtils.isNotEmpty(jstProductResDTO.getData().getDatas())) {
                    	pageCount = jstProductResDTO.getData().getPageCount();
                    	log.info("--------------- jst远程抓取{}至{}数据, 第: {} 页, 总页数: {}  当前时间: {}, 总耗时: {} 分  ---------------", startTime, endTime, pageNo, pageCount, startTime, (int) ((System.currentTimeMillis() - millis) / 1000 / 60));
						// 商品保存
						saveGoods(jstProductResDTO.getData().getDatas());
					} else {
						log.info("--------------- jst远程抓取{}至{}数据, 第: {} 页, 无数据,  当前时间: {}, 总耗时: {} 分  ---------------", startTime, endTime, pageNo, startTime, (int) ((System.currentTimeMillis() - millis) / 1000 / 60));
					}
                    Thread.sleep(1000);
				} catch (Exception e) {
					e.printStackTrace();
				}
				
				pageNo++;
			}

			startTime = endTime;
			endTime = endTime.plusDays(1);
		}
    
        return true;
    }
    
    // 商品源数据保存
    private void saveGoods(List<DataResult> goodsList) {
        // 商品数据
        List<JstProduct> goodsEntity = new ArrayList<>();
        List<JstProductSku> goodsSkuEntity = new ArrayList<>();
        
        for(DataResult result : goodsList) {
        	List<Sku> skus = result.getSkus();
        	// 查找对应库存
        	try {
        		Thread.sleep(1000);
        		List<String> skuIds = skus.stream().map(obj -> obj.getSkuId()).collect(Collectors.toList());
        		String skuIdStr = org.apache.commons.lang3.StringUtils.join(skuIds, ",");
        		JstProductStockResDTO jstProductStockResDTO = jstProductUtil.selectStock(skuIdStr);
        		if(null == jstProductStockResDTO || 0 >= jstProductStockResDTO.getData().getDataCount()) {
        			continue;
        		}
        		List<Inventory> inventorys = jstProductStockResDTO.getData().getInventorys();
        		for(Inventory inventory : inventorys) {
        			for(Sku sku : skus) {
        				if(sku.getSkuId().equals(inventory.getSkuId())) {
        					sku.setQty(inventory.getQty());
        				}
        			}
        		}
        	} catch (Exception e) {
        		e.printStackTrace();
        	}
        	
        	// 商品保存
        	JstProduct goods = new JstProduct();
        	BeanUtils.copyProperties(result, goods);
        	goodsEntity.add(goods);
        	
        	goodsSkuEntity.addAll(JSONArray.parseArray(JSON.toJSONString(skus), JstProductSku.class));
        }

        jstProductService.saveBatch(goodsEntity);
        jstProductSkuService.saveBatch(goodsSkuEntity);
    }
    
    @Override
    public Boolean pushProduct() {
        try {
            // 当次更新少于1千条, 则不更新, 并且重新拉取
            LambdaQueryWrapper<JstProduct> lambdaQueryWrapper =  new LambdaQueryWrapper<>();
//            lambdaQueryWrapper.isNotNull(JstProduct :: getSPrice);
//            lambdaQueryWrapper.isNotNull(JstProduct :: getMarketPrice);
			int count = jstProductService.count(lambdaQueryWrapper);
			/*if(1000 > count) {
			    systemConfigService.update(Wrappers.<SystemConfig>lambdaUpdate()
			            .eq(SystemConfig :: getName, Constants.JST_SYNC_STATUS)
			            .set(SystemConfig :: getFormId, SyncStatusEnum.PUSH)
			            .set(SystemConfig :: getUpdateTime, new Date())
			            );
			    log.info("--------------- jst商品源数据, 少于规定条数, 不进行下发, 总条数为: {} ---------------", count);
			    return false;
			}*/
            
            // 将所有jst商品更新状态置为未更新
            storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .eq(StoreProduct :: getIsEurope, ProductTypeEnum.JST.getCode())
                    .set(StoreProduct :: getUpdateFlag, false)
                    );
            
            // 商品更新操作
            int pageNo = 1;
            int pageSize = 100;
            int maxPage = (count + pageSize - 1) / pageSize;
            log.info("--------------- 开始分页查询jst商品源数据, 本次更新总条数为: {} ---------------", count);

            long millis = System.currentTimeMillis();
            while (pageNo <= maxPage) {
                try {
                    PageHelper.startPage(pageNo, pageSize);
                    List<JstProduct> jstProducts = jstProductService.list(lambdaQueryWrapper);
                    PageInfo<JstProduct> pageInfo = PageInfo.of(jstProducts);
                    List<JstProduct> products = pageInfo.getList();
                    buildProduct(products);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                log.info("--------------- jst下发商品到数据库, 当前页数: {}, 总页数: {}, 耗时: {} 分 ---------------", pageNo, maxPage, (int)((System.currentTimeMillis() - millis) / 1000 / 60));
                pageNo++;
            }
            // 图搜删除
            storeProductService.delSeachImage(ProductTypeEnum.JST);
            // 下架所有未更新数据
            storeProductService.update(Wrappers.<StoreProduct>lambdaUpdate()
                    .eq(StoreProduct::getIsEurope, ProductTypeEnum.JST.getCode())
                    .eq(StoreProduct::getUpdateFlag, false)
                    .eq(StoreProduct :: getIsShow, true)
                    .eq(StoreProduct :: getIsDel, false)
                    .set(StoreProduct::getIsShow, false)
                    .set(StoreProduct::getStock, 0)
                    .set(StoreProduct::getLastPushTime, new Date())
                    .set(StoreProduct::getIsTusou, false)
                    );
            // 下架所有sku库存
            storeProductService.downloadSku(ProductTypeEnum.JST.getCode());

            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return false;
    }

    /**
     * 商品构建处理
     * @Description:  
     * @author daigb 
     * @param @param products
     * @return void
     * @throws
     */
    private void buildProduct(List<JstProduct> products) {
        try {
            for (JstProduct product : products) {
                // sku数据
                List<JstProductSku> skus = jstProductSkuService.list(Wrappers.<JstProductSku>lambdaQuery()
                		.eq(JstProductSku :: getIId, product.getIId())
                		.eq(JstProductSku :: getEnabled, 1)
                		.gt(JstProductSku :: getQty, 0)
                		);
                if(CollectionUtils.isEmpty(skus)) {
                    continue;
                }
                // 计算库存
                int stock = 0;
                for(JstProductSku sku : skus) {
                	stock += sku.getQty();
                }
                if (0 >= stock) {
                    continue;
                }

                // 构建实体
                StoreProductCrmebRequest storeProductCrmebRequest = sourceJstProductUtil.buildCrmebProduct(product, skus, stock);
                if(null == storeProductCrmebRequest) {
                    continue;
                }
                // 主商品下放草稿箱
                StoreProductDraft storeProductDraft = new StoreProductDraft();
                BeanUtils.copyProperties(storeProductCrmebRequest, storeProductDraft);
                storeProductDraftService.save(storeProductDraft);
                // 子商品下放草稿箱
                List<StoreProductAttrValueRequest> storeProductAttrValuesRequest = storeProductCrmebRequest.getAttrValue();
                List<StoreProductAttrValueDraft> values = new ArrayList<>();
                for (StoreProductAttrValueRequest attrValuesRequest : storeProductAttrValuesRequest) {
                	// 聚水潭商品SKU使用主图替换
                    attrValuesRequest.setProductId(storeProductDraft.getId());
                    attrValuesRequest.setBarCode(storeProductDraft.getBarCode());
                    attrValuesRequest.setSourceSkuId(storeProductCrmebRequest.getIsEurope()+"-"+attrValuesRequest.getSourceSkuId());
                    StoreProductAttrValueDraft spav = new StoreProductAttrValueDraft();
                    BeanUtils.copyProperties(attrValuesRequest, spav);
                    List<String> skuList = new ArrayList<>();
                    for (Map.Entry<String, String> vo : attrValuesRequest.getAttrValue().entrySet()) {
                        skuList.add(vo.getValue());
                        spav.setSuk(String.join(",", skuList));
                    }
                    spav.setAttrValue(JSON.toJSONString(attrValuesRequest.getAttrValue()));
                    values.add(spav);
                }
                storeProductAttrValueDraftService.saveBatch(values);
                
                // 数据保存
//                StoreProduct storeProduct = storeProductService.getByBarCode(storeProductCrmebRequest.getBarCode());
//                storeProductService.saveOtProduct(storeProductCrmebRequest, storeProduct, stock);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
}
